package com.cww.study.exceptionHandler;

import com.cww.study.event.Event;
import com.cww.study.event.ExceptionListener;
import com.cww.study.utils.ApplicationPropertiesUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: myes
 * @description: 处理配置文件配置的自定义异常过滤器
 * @author: 陈英俊
 * @create: 2021-09-09 14:38
 */
public class ErrorFilterHandler implements Filter {
    private final Logger logger = LoggerFactory.getLogger(ErrorFilterHandler.class);

    public ErrorFilterHandler() {
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.logger.info("init ErrorFilterHandler...");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        // 得到HttpServletResponse对象
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        // 放行的时候 ,捕获所有异常,进行封装
        try {
            chain.doFilter(request, response);
        } catch (Throwable var8) {
            Object ret = this.processException(var8);
            if (ret == null) {
                // 没有配置自定义异常路径才会到这里 抛出异常
                throw var8;
            }
            // 配置了异常路径 走到这里
            response.setContentType("text/plain;charset=UTF-8");
            ObjectMapper mapper = new ObjectMapper();
            // 得到响应的文本输出流, 将ret写道输出流
            httpServletResponse.getWriter().append(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(ret));
            httpServletResponse.flushBuffer();
        }

    }

    private Object processException(Throwable ex) {
        // 得到自定异常路径
        String exceptionListenerPath = ApplicationPropertiesUtil.getProperty("cl.listener.classpath.exception");
        Event eventSource = new Event();
        Object ret = null;
        if (StringUtils.isNotBlank(exceptionListenerPath)) {
            try {
                eventSource.setExceptionListener((ExceptionListener) Class.forName(exceptionListenerPath).newInstance());
                ret = eventSource.responseException((Exception) ex);
            } catch (Exception var6) {
                this.logger.error("实例化listener失败", ex.getMessage());
            }
        }

        return null;
    }

    @Override
    public void destroy() {
    }
}
